package io.gitee.zhangbinhub.admin.deploy.controller

import cn.dev33.satoken.annotation.SaCheckRole
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.deploy.constant.DeployApi
import io.gitee.zhangbinhub.admin.deploy.po.FilePo
import io.gitee.zhangbinhub.admin.deploy.service.DeployFileService
import io.gitee.zhangbinhub.admin.deploy.vo.FileVo
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.bouncycastle.util.encoders.Base64
import org.noear.snack4.ONode
import org.noear.solon.annotation.Body
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Mapping
import org.noear.solon.annotation.Param
import org.noear.solon.core.handle.Context
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.handle.UploadedFile
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.NotBlank
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("文件管理")
open class DeployFileController(
    logAdapter: LogAdapter,
    private val deployFileService: DeployFileService
) : BaseResourceServerController(logAdapter) {
    @ApiOperation("创建文件夹")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.PUT],
        value = DeployApi.basePath + DeployApi.file,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun createFold(@Body @Validated filePo: FilePo): FileVo =
        deployFileService.createFold(filePo.path ?: "", filePo.name!!)

    @ApiOperation("查询服务器文件")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.GET],
        value = DeployApi.basePath + DeployApi.file,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun queryFile(
        @ApiParam(name = "路径", required = false)
        @Param(name = "path", required = false) path: String?,
        @ApiParam(name = "名称", required = false)
        @Param(name = "name", required = false) name: String?
    ): List<FileVo> = (path?.let {
        String(Base64.decode(it), CommonTools.getDefaultCharset())
    } ?: "").let { basePath ->
        (name?.let {
            String(Base64.decode(it), CommonTools.getDefaultCharset())
        } ?: "").let { filterName ->
            deployFileService.fileList(basePath, filterName)
        }
    }

    @ApiOperation("上传文件")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.POST],
        value = DeployApi.basePath + DeployApi.file,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun uploadFile(
        @ApiParam(name = "路径", required = false)
        @Param(name = "path", required = false) path: String?,
        @ApiParam(name = "文件", required = true)
        @Param(name = "file") file: UploadedFile
    ): FileVo {
        if (file.isEmpty) {
            throw WebException("请选择需要上传的文件")
        }
        return deployFileService.uploadFile(path ?: "", file)
    }

    @ApiOperation("删除文件")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.DELETE],
        value = DeployApi.basePath + DeployApi.file,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun deleteFile(@Body @Validated filePo: FilePo): InfoVo {
        return deployFileService.deleteFile(filePo.path ?: "", filePo.name!!).let {
            InfoVo(message = "文件删除成功")
        }
    }

    @ApiOperation("下载文件")
    @Mapping(
        method = [MethodType.GET],
        value = DeployApi.basePath + DeployApi.fileDownLoad,
        produces = MimeType.ALL_VALUE
    )
    @Throws(WebException::class)
    fun downloadFile(
        context: Context,
        @ApiParam(name = "文件内容", required = true)
        @NotBlank(message = "文件内容不能为空")
        @Param(name = "params") params: String
    ) {
        val filePo: FilePo = ONode.deserialize(params, FilePo::class.java)
        if (CommonTools.isNullStr(filePo.name)) {
            throw WebException("文件名称不能为空")
        }
        val basePath = String(Base64.decode(filePo.path), CommonTools.getDefaultCharset())
        val fileName = String(Base64.decode(filePo.name), CommonTools.getDefaultCharset())
        deployFileService.doDownLoadFile(context, basePath, fileName)
    }
}